package com.project.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: JsonUtils
 * @Author: kang
 * @Date: 2021/3/18　18:58
 * @Description：json工具类
 */
public class JsonUtils {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    private static final SerializerFeature nullValue = SerializerFeature.WriteMapNullValue;

    private static final ObjectMapper objectMapperLowerCaseWithUnderScores = new ObjectMapper();

    static {
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        objectMapperLowerCaseWithUnderScores.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        objectMapperLowerCaseWithUnderScores.setPropertyNamingStrategy(new PropertyNamingStrategy.SnakeCaseStrategy());
    }

    private JsonUtils() {
    }

    public static List<T> jsonToList(JSON json, Class<? extends T> aClass) {
        List<T> infos = new ArrayList<>();
        JSONArray array = JSONArray.parseArray(json.toJSONString());
        for (int i = 0; i < array.size(); i++) {
            Object o = array.get(i);
            if (o == null) {
                o = "";
            }
            infos.add(JsonUtils.jsonToBean(o.toString(), aClass));
        }
        return infos;
    }

    //不忽略空值
    public static JSONObject toJson(Object object) {
        return object != null ? JSON.parseObject(JSON.toJSONString(object, nullValue)) : new JSONObject();
    }

    //不忽略空值
    public static String toString(JSON json) {
        return json == null ? "" : JSON.toJSONString(json, nullValue).replaceAll(":null,", ":\"\",");
    }

    public static <T> T beanToBean(Object o, Class<T> classType) {
        return jsonToBean(beanToJson(o), classType);
    }

    public static JSONObject beanToJSON(Object object) {
        return object != null ? JSON.parseObject(JSON.toJSONString(object)) : new JSONObject();
    }

    public static String beanToJson(Object object) {
        if (object != null) {
            try {
                return objectMapper.writeValueAsString(object);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    public static <T> T jsonToBean(String json, Class<T> classType) {
        if (StringUtils.isNotBlank(json) && classType != null) {
            try {
                return objectMapper.readValue(json, classType);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static <T> List<T> jsonToList(String json, Class<T> classType) {
        if (StringUtils.isNotBlank(json) && classType != null) {
            try {
                return objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, classType));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static <k, v> Map<k, v> jsonToMap(String json, Class<k> kType, Class<v> vType) {
        if (StringUtils.isNotBlank(json)) {
            try {
                return objectMapper.readValue(json, objectMapper.getTypeFactory().constructMapType(Map.class, kType, vType));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static String beanToJsonByLowerCase(Object object) {
        if (object != null) {
            try {
                return objectMapperLowerCaseWithUnderScores.writeValueAsString(object);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    public static <T> T jsonToBeanByLowerCase(String json, Class<T> classType) {
        if (StringUtils.isNotBlank(json)) {
            try {
                return objectMapperLowerCaseWithUnderScores.readValue(json, classType);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
